﻿#pragma once

#include <xy/ais/object.h>

namespace xy
{

namespace ais
{

class context
{
    enum Action3d
    {
        None,
        Rotate,
        Translate
    };

  public:
    /**
     * @brief 初始化
     *
     * @param[in] width
     * @param[in] height
     */
    context(int width, int height);

    /**
     * @brief 鼠标滚轮消息
     *
     * @param[in] angleDelta
     */
    void mouse_wheel_event(float angleDelta);

    /**
     * @brief 鼠标按压消息
     *
     * @param pos
     * @param button
     */
    void mouse_press_event(const geom::vec2f &pos, msg_mouse::Button button);

    /**
     * @brief 鼠标释放消息
     *
     * @param pos
     */
    void mouse_release_event(const geom::vec2f &pos);

    /**
     * @brief 鼠标移动消息
     *
     * @param pos
     */
    void mouse_move_event(const geom::vec2f &pos);

    /**
     * @brief 窗口大小变化消息
     *
     * @param[in] width
     * @param[in] height
     */
    void resize_event(int width, int height);

    /**
     * @brief 键盘消息
     *
     * @param[in] key
     */
    void key_event(int key);

    /**
     * @brief 绘制事件
     *
     */
    void paint_event();

    /**
     * @brief 添加物体
     *
     * @param[in] obj
     */
    void add_object(std::shared_ptr<object> obj);

    /**
     * @brief 注册渲染器
     *
     * @param[in] name
     * @param[in] func
     */
    void register_renderer(std::string name, std::function<renderer *()> func);

    /**
     * @brief 获得消息对象
     *
     * @return std::shared_ptr<msg_mouse>
     */
    std::shared_ptr<msg_mouse> msg() const;

    /**
     * @brief 获得屏幕坐标对应的空间坐标
     *
     * @param[in] pos
     * @return geom::vec3f
     */
    geom::vec3f space_mapping(const geom::vec2f &pos) const;

    /**
     * @brief 获得空间坐标对应的屏幕坐标
     *
     * @param[in] pos
     * @return geom::vec3f
     */
    geom::vec3f screen_mapping(const geom::vec3f &pos) const;

  private:
    float m_angleRate{0.25f};
    float m_scaleRate{2.0f};
    Action3d m_action{None};
    std::shared_ptr<msg_mouse> m_mouseMsg;
    std::shared_ptr<renderer_factory> m_rendererFactory;
    std::vector<std::shared_ptr<object>> m_objects;
};

} // namespace ais

} // namespace xy
